package com.boe.csb.core.service.user;

import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.boe.csb.core.common.utils.HttpUtils;
import com.boe.csb.core.common.utils.HttpUtils.HttpResult;
import com.boe.csb.core.dao.BoeUserMapper;
import com.boe.csb.core.entity.CloudErrorBean;
import com.boe.csb.core.entity.CloudStatisticsBean;
import com.boe.csb.core.entity.SimplePageInfo;
import com.boe.csb.core.entity.po.BoeUser;

@Service("boeCloudLogService")
public class BoeCloudLogService {
	private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	private static String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0ZW5hbnRfaWQiOiIzMzA2IiwidXNlcl9pZCI6IjI1MTciLCJleHAiOjE0OTc5MDAwOTEsInVzZXJfbmFtZSI6ImNzYi1hZG1pbkBib2UuY29tLmNuIn0.p9X9f6rpvcB0rrFqksz2SEEY_gFTkne04B3HoUm7bKY";
	private static Map<String,String> callerMap = new ConcurrentHashMap<String, String>();
	private static Map<String,String> rUserIDMap = new ConcurrentHashMap<String, String>();
	private static Map<String,String> rUserNameMap = new ConcurrentHashMap<String, String>();
	
	@Autowired
	private HttpUtils HttpUtils;
	@Autowired
	private BoeUserMapper boeUserMapper;
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public SimplePageInfo queryCloudErrorLog(String startTime,String endTime,Integer size,Integer page){
		String url = "page="+page+"&";
		url += "query=appname:%22csb_broker_error%22+AND+-message:%22get+serviceModels+from+cache+size+is+0+!+%22&";
		url += "size="+size+"&";
		url += "startTime="+startTime+","+endTime+"&";
		url += "time_range="+startTime+","+endTime+"&";
		
		JSONObject jObject= returnLogInfo(url);
		if(jObject != null){
			JSONArray jArray= (JSONArray) jObject.get("events");
			List<CloudErrorBean> list = new ArrayList<CloudErrorBean>();
			for(int i=0;i<jArray.size();i++){
				Object js1 = jArray.get(i);
				JSONObject map2 = JSONObject.parseObject(js1.toString());
				JSONArray jArray1 = (JSONArray) map2.get("log_source");
				for(int j=0;j<jArray1.size();j++){
					JSONObject js2 = jArray1.getJSONObject(j);
					String timestamp = js2.getString("@timestamp");
					String message = js2.getString("message");
//					if(message.indexOf(str1) < 0 && message.indexOf(str2) < 0){
						String tag = js2.getString("tag");
						String agent_type = js2.getString("agent_type");
						String logtype = js2.getString("logtype");
						String appname = js2.getString("appname");
						String path = js2.getString("path");
						String hostname = js2.getString("hostname");
						CloudErrorBean bean = new CloudErrorBean();
						bean.setTimestamp(timestamp);
						bean.setAgent_type(agent_type);
						bean.setAppname(appname);
						bean.setHostname(hostname);
						bean.setLogtype(logtype);
						bean.setMessage(message);
						bean.setPath(path);
						bean.setTag(tag);
						list.add(bean);
					}
//				}
			}
			return new SimplePageInfo(list,Long.valueOf(jObject.get("total").toString()));
		}
		return null;
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public SimplePageInfo queryStatisticsLog(String startTime,String endTime,String apiName,String apiRelease,String apiCaller,Integer size,Integer page,Integer flag){
		String query = "query=appname:%22csb_broker_invoke%22";
		Set<String> set = null; 
		if(!StringUtils.isBlank(apiRelease)){
			List<String> list = boeUserMapper.loadApiName("%"+apiRelease+"%");
			set = new HashSet<String>(list);
		}
		
		if(set == null && !StringUtils.isBlank(apiName)){
			query += "+AND+serviceName:%22"+apiName+"%22";
		}else if(set != null && StringUtils.isBlank(apiName)){
			String serName = "";
			for(String s:set){
				serName += "serviceName:%22"+s+"%22+OR+";
			}
			if(serName.length() > 4){
				serName = serName.substring(0, serName.length()-4);
				query += "+AND+("+serName+")";
			}
		}else if(set != null && !StringUtils.isBlank(apiName)){
			set.add(apiName);
			String serName = "";
			for(String s:set){
				serName += "serviceName:%22"+s+"%22+OR+";
			}
			if(serName.length() > 4){
				serName = serName.substring(0, serName.length()-4);
				query += "+AND+("+serName+")";
			}
		}
		
		if(!StringUtils.isBlank(apiCaller)){
			List<Long> list = boeUserMapper.loadBoeUserID("%"+apiCaller+"%");
			if(list != null && list.size() > 0){
				String caller = "";
				for(int i=0;i<list.size();i++){
					caller += "userID:%22"+list.get(i)+"%22+OR+";
				}
				if(caller.length() > 4){
					caller = caller.substring(0, caller.length()-4);
					query += "+AND+("+caller+")";
				}
			}
		}
		
		if(flag == 1){
			query += "+AND+errorCode:%22200%22";
		}else if(flag ==2){
			query += "+AND+(errorCode:1*+OR+errorCode:3*+OR+errorCode:4*+OR+errorCode:5*)";
		}
		
		String url = "page="+page+"&";
		url += query;
		url += "&";
		url += "size="+size+"&";
		url += "startTime="+startTime+","+endTime+"&";
		url += "time_range="+startTime+","+endTime+"&";

		JSONObject jObject = returnLogInfo(url);
		if(jObject != null){
			JSONArray jArray= (JSONArray) jObject.get("events");
			List<CloudStatisticsBean> list = new ArrayList<CloudStatisticsBean>();
			for(int i=0;i<jArray.size();i++){
				Object js1 = jArray.get(i);
				JSONObject map2 = JSONObject.parseObject(js1.toString());
				JSONArray jArray1 = (JSONArray) map2.get("log_source");
				for(int j=0;j<jArray1.size();j++){
					JSONObject js2 = jArray1.getJSONObject(j);
					String time = js2.getString("@timestamp");
					CloudStatisticsBean bean = JSONObject.parseObject(js2.toJSONString(), CloudStatisticsBean.class);
					bean.setTimestamp(time);
					String serverName1 = bean.getServiceName();
					if(serverName1.indexOf(":") >= 0){
						String serverName = serverName1.split(":")[0];
						if(!StringUtils.isBlank(serverName)){
							if(StringUtils.isBlank(rUserIDMap.get(serverName)) || StringUtils.isBlank(rUserNameMap.get(serverName))){
								Map<String,Object> emailMap = boeUserMapper.loadBoeUserEmail(serverName);
								if(emailMap != null && !emailMap.isEmpty()){
									String email = emailMap.get("email").toString();
									String userid = emailMap.get("id").toString();
									bean.setrUserID(userid);
									bean.setrUserName(email);
									rUserIDMap.put(serverName, userid);
									rUserNameMap.put(serverName, email);
								}
							}else{
								bean.setrUserID(rUserIDMap.get(serverName));
								bean.setrUserName(rUserNameMap.get(serverName));
							}
						}
					}
					String userID = bean.getUserID();
					if(!StringUtils.isBlank(userID)){
						if(StringUtils.isBlank(callerMap.get(userID))){
							BoeUser boeUser = boeUserMapper.selectByPrimaryKey(Long.valueOf(userID));
							if(boeUser != null){
								bean.setUserName(boeUser.getEmail());
								callerMap.put(userID, boeUser.getEmail());
							}
						}else{
							bean.setUserName(callerMap.get(userID));
						}
					}
					list.add(bean);
				}
			}
			return new SimplePageInfo(list,Long.valueOf(jObject.get("total").toString()));
		}
		return null;
	}
	
	
	private JSONObject returnLogInfo(String parameter){
		String url = "http://easylogapi.boe.com.cn/api/v1/search/events?";
		url += parameter;
		url += "time_type=0&tenant_id=3306&order=desc&log_group_id=0&user_id=2517";
		
		Long unix = null;
		try{
			unix = decode_token(token);
			if(unix < returnDate() ){
				unix += 2000000;
				token = encode_token(unix*1000);
			}
		}catch(Exception e){
			unix = new Date().getTime() + Long.valueOf("2000000000");
			token = encode_token(unix);
		}
		
		String cookie = "dt_token="+token;
		
		HttpResult httpResult = HttpUtils.doGetString(url,cookie);
		
		String json = httpResult.getBody();

		JSONObject js = JSONObject.parseObject(json);
		if(!js.isEmpty() && js.get("result_code").toString().equals("1")){
			JSONObject map1 = JSONObject.parseObject(js.get("data").toString());
			return map1;
		}else{
			System.out.println("------------------------------------------------");
			System.out.println(json);
			System.out.println("------------------------------------------------");
		}
		return null;
		
	}
	
	public Long decode_token(String token) throws Exception{
		JWTVerifier verifier = JWT.require(Algorithm.HMAC256("279bef3e9703712f")).build();
		DecodedJWT jwt = verifier.verify(token);  
        Map<String, Claim> claims = jwt.getClaims();  
        return claims.get("exp").asLong();
	}
	
	public String encode_token(Long unix){
		System.out.println(unix);
		Map<String, Object> map = new HashMap<String, Object>();  
        map.put("alg", "HS256");  
        map.put("typ", "JWT");  
        String token = "";
		try {
			token = JWT.create()  
			        .withHeader(map)//header  
			        .withClaim("tenant_id", 3306)
			        .withExpiresAt(new Date(unix))
			        .withClaim("user_id", "2517")
			        .withClaim("user_name", "csb-admin@boe.com.cn")		
			        .sign(Algorithm.HMAC256("279bef3e9703712f"));
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (JWTCreationException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}//加密  
		//生成JWT
		return token;
	}
	
	//获取明天同时间时间戳
	private static Long returnDate(){
		Calendar cl = Calendar.getInstance();
		Date date = new Date();
		cl.setTime(date);
		cl.add(Calendar.DATE, 1);
		System.out.println(sdf.format(cl.getTime()));
		return cl.getTimeInMillis()/1000;
		
	}
	
	public static void main(String[] args){
		Set<String> set = new HashSet<String>();
		set.add("asd");
		set.add("123");
		set.add("369");
		String serName = "";
		for(String s:set){
			serName += "serviceName:%22"+s+"%22+OR+";
		}
		serName = serName.substring(0, serName.length()-4);
		System.out.println(serName);
	}
	
}
